"""
cURL响应解析器
负责解析和格式化curl响应数据
"""
import json
import logging
from typing import Dict, Any

logger = logging.getLogger(__name__)


class CurlResponseParser:
    """cURL响应解析器"""
    
    def __init__(self):
        self.logger = logger
    
    def parse_response_for_mock(self, response_data: Dict) -> Dict:
        """
        将curl响应数据转换为适合Mock规则的格式
        
        Args:
            response_data: curl执行器返回的响应数据
            
        Returns:
            dict: 适合Mock规则的数据格式
        """
        mock_data = {
            'status_code': 200,
            'content_type': 'application/json',
            'content': '',
            'headers': {}
        }
        
        try:
            # 状态码
            if response_data.get('status_code'):
                mock_data['status_code'] = response_data['status_code']
            
            # 内容类型
            if response_data.get('content_type'):
                mock_data['content_type'] = response_data['content_type']
            
            # 响应内容
            content = response_data.get('content', '')
            if content:
                # 根据内容类型处理
                mock_data['content'] = self._format_content(
                    content, 
                    mock_data['content_type']
                )
            else:
                # 提供默认内容
                mock_data['content'] = self._generate_default_content(
                    mock_data['content_type']
                )
            
            # 响应头（过滤和清理）
            headers = response_data.get('headers', {})
            mock_data['headers'] = self._filter_headers_for_mock(headers)
            
            self.logger.info(f"成功解析响应数据为Mock格式")
            
        except Exception as e:
            self.logger.error(f"响应数据解析失败: {e}")
            # 返回默认Mock数据
            mock_data['content'] = json.dumps({
                "error": "响应解析失败",
                "message": str(e)
            }, indent=2, ensure_ascii=False)
        
        return mock_data
    
    def _format_content(self, content: str, content_type: str) -> str:
        """
        根据内容类型格式化内容
        
        Args:
            content: 原始内容
            content_type: 内容类型
            
        Returns:
            str: 格式化后的内容
        """
        try:
            if content_type.startswith('application/json'):
                # JSON格式化
                return self._format_json_content(content)
            elif content_type.startswith('application/xml') or content_type.startswith('text/xml'):
                # XML格式化
                return self._format_xml_content(content)
            elif content_type.startswith('text/html'):
                # HTML格式化
                return self._format_html_content(content)
            else:
                # 其他格式保持原样
                return content.strip()
                
        except Exception as e:
            self.logger.warning(f"内容格式化失败: {e}")
            return content
    
    def _format_json_content(self, content: str) -> str:
        """格式化JSON内容"""
        try:
            # 尝试解析并重新格式化JSON
            data = json.loads(content)
            return json.dumps(data, indent=2, ensure_ascii=False)
        except json.JSONDecodeError:
            # 如果不是有效JSON，返回原内容
            return content
    
    def _format_xml_content(self, content: str) -> str:
        """格式化XML内容"""
        try:
            import xml.dom.minidom
            dom = xml.dom.minidom.parseString(content)
            return dom.toprettyxml(indent="  ")
        except:
            return content
    
    def _format_html_content(self, content: str) -> str:
        """格式化HTML内容"""
        try:
            from bs4 import BeautifulSoup
            soup = BeautifulSoup(content, 'html.parser')
            return soup.prettify()
        except ImportError:
            # 如果没有BeautifulSoup，返回原内容
            return content
        except:
            return content
    
    def _generate_default_content(self, content_type: str) -> str:
        """
        生成默认Mock内容
        
        Args:
            content_type: 内容类型
            
        Returns:
            str: 默认内容
        """
        if content_type.startswith('application/json'):
            return json.dumps({
                "message": "Mock response generated from cURL execution",
                "timestamp": self._get_current_timestamp(),
                "data": {}
            }, indent=2, ensure_ascii=False)
        elif content_type.startswith('text/html'):
            return """<!DOCTYPE html>
<html>
<head>
    <title>Mock Response</title>
</head>
<body>
    <h1>Mock Response</h1>
    <p>This is a mock response generated from cURL execution.</p>
</body>
</html>"""
        elif content_type.startswith('text/plain'):
            return "Mock response generated from cURL execution"
        else:
            return json.dumps({
                "message": "Mock response",
                "content_type": content_type
            }, indent=2, ensure_ascii=False)
    
    def _filter_headers_for_mock(self, headers: Dict[str, str]) -> Dict[str, str]:
        """
        过滤和清理响应头，只保留适合Mock的头部
        
        Args:
            headers: 原始响应头
            
        Returns:
            dict: 过滤后的响应头
        """
        # 适合Mock的响应头
        mock_headers = {}
        
        # 保留的响应头类型
        keep_headers = [
            'content-type',
            'cache-control',
            'access-control-allow-origin',
            'access-control-allow-methods',
            'access-control-allow-headers',
            'access-control-allow-credentials',
            'x-ratelimit-limit',
            'x-ratelimit-remaining',
            'x-api-version'
        ]
        
        for key, value in headers.items():
            key_lower = key.lower()
            
            # 保留指定的响应头
            if any(keep_key in key_lower for keep_key in keep_headers):
                mock_headers[key] = value
            # 保留自定义响应头（以x-开头）
            elif key_lower.startswith('x-') and not key_lower.startswith('x-request'):
                mock_headers[key] = value
        
        # 添加默认的Mock标识头
        mock_headers['X-Mock-Generated'] = 'true'
        
        return mock_headers
    
    def _get_current_timestamp(self) -> str:
        """获取当前时间戳"""
        import datetime
        return datetime.datetime.now().isoformat()
    
    def validate_mock_content(self, content: str, content_type: str) -> Dict:
        """
        验证Mock内容的有效性
        
        Args:
            content: Mock内容
            content_type: 内容类型
            
        Returns:
            dict: 验证结果
        """
        result = {
            'valid': True,
            'error': None,
            'warnings': []
        }
        
        try:
            if content_type.startswith('application/json'):
                # 验证JSON格式
                json.loads(content)
            elif content_type.startswith('application/xml'):
                # 验证XML格式
                import xml.etree.ElementTree as ET
                ET.fromstring(content)
            
            # 检查内容长度
            if len(content) > 1024 * 1024:  # 1MB
                result['warnings'].append("Mock内容较大，可能影响性能")
            
        except json.JSONDecodeError as e:
            result['valid'] = False
            result['error'] = f"JSON格式错误: {str(e)}"
        except ET.ParseError as e:
            result['valid'] = False
            result['error'] = f"XML格式错误: {str(e)}"
        except Exception as e:
            result['warnings'].append(f"内容验证警告: {str(e)}")
        
        return result